--[[
命令如下
    lua mcu_2ocdtcl.lua mcu.bin >out.tcl

以页对齐来输出文件
Page0 (256byte)     程序长度 4byte (大端序)
                    程序运行 RAM地址
Page1 (256byte)     程序数据


然后在openocd脚本中添加 source out.tcl

write_pos 写入位置
exec_addr 执行程序位置
]]

local _write_pos = write_pos or 0;
local _exec_addr = exec_addr or 0x0000000;

local file = io.open(arg[1],"rb");
assert(file,"error file:"..tostring(arg[1]));
local bin = file:read('*a');
local len = #bin;

local read_u8 = function(offset)
    if(offset>=len)then return 0; end
    return bin:byte(offset+1);
end

local read_u16 = function(offset)
    return read_u8(offset)+read_u8(offset+1)*0x100;
end

local read_u32 = function(offset)
    return read_u16(offset)+read_u16(offset+2)*0x10000;
end

local big32 = function(value)
    return
           (value%0x100)*0x1000000 +
math.floor((value/0x100)%0x100) * 0x10000 +
math.floor((value/0x10000)%0x100) * 0x100 +
math.floor((value/0x1000000)%0x100);
end

local format = string.format;
--设置开始编程的地址
local tcl_str = 'sflash_program_begin 0x%08x';
local cur_pos = 0;
local is_end = true;

print([[set old_debug_level [debug_level] ;set e "";set old_debug_level [regsub ":" $old_debug_level $e]; debug_level 0; ]]);

--[[设置程序头]]
local align_len = (len - (len%0x10)) + 0x10;

local pos = 0;
print(format('sflash_erase 0x%08x',pos + _write_pos));

local s = format(tcl_str,pos + _write_pos);
print(s);
print(format('sflash_send32 0x%08X',big32(align_len)));
print(format('sflash_send32 0x%08X',big32(_exec_addr)));
print(format('sflash_send32 0x0'));


local flash_write_pos = _write_pos;
if(false)then
    --对于AG10K,应该不是跳过0x100
    --而是0x10
    --然后16K的数据手册写着0x100
    print(format('sflash_program_end 0x0'));
    _write_pos = _write_pos + 0x100;
else
    --修正后的AG10K
    flash_write_pos = flash_write_pos + 0x10;
    print(format('sflash_send32 0x0'));
end



for pos=0,len-1,4 do
    if((pos%1024)==0)then
        print(format('puts "%d kbytes"',pos/1024));
    end

    if((flash_write_pos%0x100)==0)then
        --需要页对齐.一般是0x100个字节
        local s = format(tcl_str,flash_write_pos);
        print(format('sflash_erase 0x%08x',flash_write_pos));
        print(s);
    end

    local tcl_s = 'sflash_send32 0x%08X'
    is_end = false;
    if((flash_write_pos%0x100)==(0x100-4))then
        --最后一个字节
        tcl_s = 'sflash_program_end 0x%08X'
        is_end = true;
    end

    local s = format(tcl_s,read_u32(pos));
    print(s);
    flash_write_pos = flash_write_pos + 4;
end

if (not is_end)then
    print('sflash_program_end 0xffffffff');
end

print([[eval $old_debug_level]])
print('puts "flash program done!"');
